package cn.yj.wx.pay.service.handler;

import cn.yj.common.emums.PayFrom;
import cn.yj.common.exception.PayException;
import cn.yj.commons.utils.StringUtils;
import cn.yj.wx.pay.config.PayConfig;
import cn.yj.wx.pay.enrity.JSAPIPayOrderResult;
import cn.yj.wx.pay.enrity.Payer;
import cn.yj.wx.pay.enrity.WechatPayRequest;
import cn.yj.wx.pay.utils.WxPayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.util.UUID;

/**
 * 公众号场景和PC网站场景
 *
 * @author 永健
 * @since 2021-09-22 16:32
 */
public class JSAPIPay extends AbstractWxPay<JSAPIPayOrderResult, WechatPayRequest> {
    private static final Logger LOGGER = LoggerFactory.getLogger(JSAPIPay.class);
    private static final String PAY_URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
    private static final String REFUND_URL = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";

    @Override
    protected void checkPayRequestParams(WechatPayRequest wechatPayRequest) {
        // openid校验
        Payer payer = wechatPayRequest.getPayer();
        if (StringUtils.isNull(payer) || StringUtils.isBlank(payer.getOpenid())) {
            throw new PayException("缺少支付者信息:openid");
        }
    }


    /**
     * 将结果进行sign签名
     *
     * @param payResult
     */
    @Override
    protected void requestPayAfter(JSAPIPayOrderResult payResult) throws NoSuchAlgorithmException, SignatureException
            , InvalidKeyException {
        String result = payResult.getResult();
        PayConfig config = super.config();
        long timestamp = System.currentTimeMillis() / 1000;
        String nonceStr = UUID.randomUUID().toString().replaceAll("-", "");
        String packageStr = String.format("prepay_id=%s", result);

        // 签名
        String v3Sign = WxPayUtils.v3Sign(config.getAppId(), String.valueOf(timestamp), nonceStr, packageStr,
                getPrivateKey());

        JSAPIPayOrderResult.Payment payment = new JSAPIPayOrderResult.Payment();
        payment.setAppId(config.getAppId());
        payment.setNonceStr(nonceStr);
        payment.setTimeStamp(String.valueOf(timestamp));
        payment.setNonceStr(nonceStr);
        payment.setPackageStr(packageStr);
        payment.setPaySign(v3Sign);
        payResult.setPayment(payment);
        LOGGER.info(payment.toString());
    }

    @Override
    public JSAPIPayOrderResult underOrder(WechatPayRequest wechatPayRequest) {
        JSAPIPayOrderResult appPayOrderResult = super.doUnderOrder(PAY_URL, wechatPayRequest);
        appPayOrderResult.setOutTradeNo(wechatPayRequest.getOut_trade_no());
        appPayOrderResult.setTotalAmount(wechatPayRequest.getAmount().getTotal().toString());
        return appPayOrderResult;
    }

    @Override
    public boolean support(PayFrom payFrom) {
        return payFrom == PayFrom.JSAPI;
    }
}
